<script setup lang="ts">
import type { TreeInstance, TreeNodeData } from '@arco-design/web-vue'

defineOptions({
  name: 'ListTree',
})

const props = defineProps<{
  loading?: boolean
  data: any
}>()

const emit = defineEmits<{
  (e: 'select', key: string, node: any): void
}>()

const slots = useSlots()
const treeRef = ref<TreeInstance>()

// 选中节点
const selectedKeys = ref()
const onSelect = (keys: Array<any>, data: any) => {
  selectedKeys.value = keys
  // tree select事件通过.node获取数据，手动调用直接获取拿data数据
  emit('select', keys[0], data.node || data)
}

// 树节点数据
const treeData = ref<any[]>([])
watch(() => props.data, async (val) => {
  treeData.value = val || []
  await nextTick(() => {
    if (treeData.value.length && treeData.value.length > 0) {
      onSelect([treeData.value[0].id], treeData.value[0])
    }
  })
}, { immediate: true })

// 树查询
const keyword = ref('')
const filterOptions = (searchKey: string, nodeData: any) => {
  const content = nodeData.name || nodeData.title
  if (content) {
    return content.toLowerCase().includes(searchKey.toLowerCase())
  }
  return false
}
watch(keyword, (val) => {
  treeData.value = (props.data || []).filter(item => filterOptions(val, item))
})
</script>

<template>
  <a-spin :loading="loading" class="tree-spin">
    <div class="flex-x">
      <a-input-search
        v-model="keyword"
        placeholder="输入关键词搜索"
        style="margin-bottom: 8px"
      />
      <slot name="extra" />
    </div>
    <a-tree
      ref="treeRef"
      class="tree"
      :data="(treeData as TreeNodeData[])"
      :field-names="{ key: 'id' }"
      block-node
      :selected-keys="selectedKeys"
      @select="onSelect"
    >
      <template #title="nodeData">
        <slot name="node" v-bind="nodeData">
          <span>{{ nodeData.name || nodeData.title }}</span>
        </slot>
      </template>
      <template v-if="slots.action" #extra="nodeData">
        <span class="node-action">
          <a-trigger
            trigger="click"
            align-point
            animation-name="slide-dynamic-origin"
            auto-fit-transform-origin
            position="br"
            scroll-to-close
          >
            <IconMore class="node-action-icon" />
            <template #content>
              <slot name="action" v-bind="nodeData" />
            </template>
          </a-trigger>
        </span>
      </template>
    </a-tree>
  </a-spin>
</template>

<style lang="less" scoped>
// 节点图标
:deep(.arco-tree-node) {
  .arco-tree-node-switcher {
    width: 0;
    margin-right: 0px;
  }
  .arco-tree-node-title {
    padding-left: 10px;
    padding-right: 32px;
  }
  .arco-tree-node-title-text {
    width: 100%;
  }
}

.tree-spin {
  overflow: auto;
  height: 100%;
  width: 100%;
}
.node-action {
  position: absolute;
  right: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  &:hover {
    border: 1px solid var(--color-border-4);
    border-radius: 4px;
  }
}

.node-action-icon {
  font-size: 12px;
  color: var(--color-text-2);
  height: 22px;
}
</style>
